package com.example.jobback.service.recruiter.impl;

import com.alibaba.fastjson.JSON;
import com.example.jobback.common.enums.PositionStatus;
import com.example.jobback.common.enums.RecruiterType;
import com.example.jobback.common.enums.VerifyPublishPositionStatus;
import com.example.jobback.config.AuthConfig;
import com.example.jobback.dto.PositionDto;
import com.example.jobback.dto.PublishPositionDto;
import com.example.jobback.dto.UpdatePositionDto;
import com.example.jobback.mapper.CompanyMapper;
import com.example.jobback.mapper.PositionMapper;
import com.example.jobback.mapper.RecruiterMapper;
import com.example.jobback.po.*;
import com.example.jobback.req.recruiter.position.publish.PublishPositionReq;
import com.example.jobback.req.recruiter.position.publish.ResubmitPublishPositionReq;
import com.example.jobback.req.recruiter.position.search.RCrossSearchJobOrCompanyReq;
import com.example.jobback.req.recruiter.position.update.RCrossChangePositionReq;
import com.example.jobback.req.recruiter.position.update.UpdatePositionReq;
import com.example.jobback.resp.recruiter.position.GetCompanyPositionResp;
import com.example.jobback.resp.recruiter.position.GetUserPositionDetailResp;
import com.example.jobback.resp.recruiter.position.GetUserPositionResp;
import com.example.jobback.resp.recruiter.position.publish.*;
import com.example.jobback.resp.recruiter.position.search.RCrossSearchCompany;
import com.example.jobback.resp.recruiter.position.search.RCrossSearchJobOrCompanyResp;
import com.example.jobback.resp.recruiter.position.search.RCrossSearchPosition;
import com.example.jobback.resp.recruiter.position.update.CompanyPendingUpdateJobResp;
import com.example.jobback.resp.recruiter.position.update.JobChangeInformationResp;
import com.example.jobback.resp.recruiter.position.update.JobMessageResp;
import com.example.jobback.resp.recruiter.position.update.UpdatePositionResp;
import com.example.jobback.result.Result;
import com.example.jobback.service.common.UserCommonService;
import com.example.jobback.service.recruiter.RecruiterCommonService;
import com.example.jobback.service.recruiter.RecruiterPositionService;
import com.example.jobback.util.CACHEUtil;
import com.example.jobback.util.TLUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.example.jobback.util.ConstantsUtil.SMART_AGAIN_MIN_POSITIONS;
import static com.example.jobback.util.ConstantsUtil.SMART_START_MIN_POSITIONS;
import static com.example.jobback.util.RedisConstants.*;
import static java.time.LocalDateTime.now;

/**
 * @ClassName: RecruiterPositionServiceImpl
 * @Description:招聘者-职位服务实现类
 * @Author: lhb
 * @Date: 2025/6/21
 */
@Service
public class RecruiterPositionServiceImpl implements RecruiterPositionService {
    
    
    private final CACHEUtil cacheUtil;


    private final RecruiterMapper recruiterMapper;

    private final CompanyMapper companyMapper;

    private final Random random=new Random();

    private final RecruiterCommonService recruiterCommonService;
    
    private final AuthConfig authConfig;

    private final PositionMapper positionMapper;
    
    private final UserCommonService userCommonService;

    public RecruiterPositionServiceImpl(CACHEUtil cacheUtil, UserCommonService userCommonService, AuthConfig authConfig, PositionMapper positionMapper, RecruiterCommonService recruiterCommonService, CompanyMapper companyMapper, RecruiterMapper recruiterMapper) {
        this.cacheUtil = cacheUtil;
        this.userCommonService = userCommonService;
        this.authConfig = authConfig;
        this.positionMapper = positionMapper;
        this.recruiterCommonService = recruiterCommonService;
        this.companyMapper = companyMapper;
        this.recruiterMapper = recruiterMapper;
    }

    /**
     * @Description: 发布岗位
     * @param req 
     * @return Result<PublishPositionResp>
     * @Author lhb
     * @CreateTime 2025/6/21 10:02
     */
    @Override
    public Result<PublishPositionResp> publishPosition(PublishPositionReq req) {
        if(req.getLowestSalaryMonth()>req.getHighestSalaryMonth()){
            throw new IllegalArgumentException("CLIENT_ERROR：最低薪资必须小于最高薪资");
        }
        //req转成dto
        Recruiter recruiter= TLUtil.get(TLUtil.R);
        //公司地址代表职位地址
        Long companyId=recruiter.getCompanyId();
        Company company = recruiterCommonService.getCompanyMessage(companyId);
        String location=company.getLocation();
        PublishPositionDto dto=new PublishPositionDto();
        BeanUtils.copyProperties(req, dto);
        dto.setUserId(recruiter.getUserId());
        dto.setStartAt(now());
        dto.setCompanyId(companyId);
        dto.setLocation(location);
        //构建code
        String hourPart = now().format(DateTimeFormatter.ofPattern("MMddHH"));
        String randomCode = String.format("%04d", random.nextInt(10000));
        String code=companyId.toString()+hourPart+randomCode;
        //将code储存到com,recruiter,manager中的set中，并且code为key，dto为value
        if(!recruiter.getType().equals(RecruiterType.RECRUITER)){
            //管理员或者boss不用审核，直接移交系统管理员审核.但是还是要将code存储在公司
            //公司储存的code即便是公司审核失败也不会删除
            //com-code
            cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY+companyId,code,System.currentTimeMillis());
            //manager-code
            cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_MANAGER_CODE_KEY,code,System.currentTimeMillis());
            //设置状态
            dto.setStatus(VerifyPublishPositionStatus.VERIFY_MANAGER_REVIEW);
        }
        else {
            //如果不是管理员，等待公司管理员审核，再等待系统管理员审核
            //com-code
            cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY+companyId,code,System.currentTimeMillis());
            //设置状态
            dto.setStatus(VerifyPublishPositionStatus.VERIFY_COMPANY_REVIEW);
        }
        //recruiter-code
        cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_RECRUITER_CODE_KEY+recruiter.getUserId(),code,System.currentTimeMillis());
        //code为key，dto为value
        String dtoJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_PUBLISH_POSITION_KEY+code,dtoJson);
        //返回响应体
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL, TimeUnit.DAYS);
        PublishPositionResp resp=new PublishPositionResp();
        if(token==null) return Result.error(resp,"token生成失败");
        resp.setCode(code);
        resp.setToken(token);
        resp.setStatus(dto.getStatus());
        return Result.success(resp);
    }

    /**
     * @Description: 取消发布岗位
     * @param code 
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:05
     */
    @Override
    public Result<Object> cancelPublishPosition(String code) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_PUBLISH_POSITION_KEY + code);
        if(dtoJson==null) throw new RuntimeException("该岗位已被删除");
        PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
        if (!dto.getUserId().equals(recruiter.getUserId())) throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        Long companyId=recruiter.getCompanyId();
        Long userId=recruiter.getUserId();
        if(dto.getStatus().equals(VerifyPublishPositionStatus.VERIFY_MANAGER_REVIEW)){
            //manager-code
            cacheUtil.removeMember(VERIFY_RECRUITER_PUBLISH_POSITION_MANAGER_CODE_KEY,code);
        }
        //com-code
        cacheUtil.removeMember(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY+companyId,code);
        //recruiter-code
        cacheUtil.removeMember(VERIFY_RECRUITER_PUBLISH_POSITION_RECRUITER_CODE_KEY+userId,code);
        //删除职位信息redis记录
        cacheUtil.deleteKeySafely(VERIFY_RECRUITER_PUBLISH_POSITION_KEY+code);
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 重新提交发布岗位
     * @param req 
     * @return Result<ResubmitPublishPositionResp>
     * @Author lhb
     * @CreateTime 2025/6/21 10:06
     */
    @Override
    public Result<ResubmitPublishPositionResp> resubmitPublishPosition(ResubmitPublishPositionReq req) {
        if(req.getLowestSalaryMonth()>req.getHighestSalaryMonth()){
            throw new IllegalArgumentException("CLIENT_ERROR：最低薪资必须小于最高薪资");
        }
        ResubmitPublishPositionResp resp=new ResubmitPublishPositionResp();
        String code=req.getCode();
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        //获取信息
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_PUBLISH_POSITION_KEY + code);
        if(dtoJson==null) throw new IllegalArgumentException("VALIDATION_ERROR：该岗位还未发布");
        PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
        if(!dto.getUserId().equals(recruiter.getUserId())) throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        VerifyPublishPositionStatus status=dto.getStatus();
        //判断是不是在管理员审核状态，如果是删掉redis记录
        if(status.equals(VerifyPublishPositionStatus.VERIFY_MANAGER_REVIEW)){
            //manager-code
            cacheUtil.removeMember(VERIFY_RECRUITER_PUBLISH_POSITION_MANAGER_CODE_KEY,code);
        }
        //根据code，修改redis信息
        BeanUtils.copyProperties(req, dto);
        //判断是不是管理员或者boss，给定初始审核状态
        if(!recruiter.getType().equals(RecruiterType.RECRUITER)){
            //公司不用审核
            dto.setStatus(VerifyPublishPositionStatus.VERIFY_MANAGER_REVIEW);
            //manager-code
            cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_MANAGER_CODE_KEY,code,System.currentTimeMillis());
        }else {
            dto.setStatus(VerifyPublishPositionStatus.VERIFY_COMPANY_REVIEW);
        }
        //消除错误反馈信息
        dto.setFailedMessage(null);
        //更新redis的岗位信息
        String dtoNewJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_PUBLISH_POSITION_KEY+code,dtoNewJson);
        //返回响应体
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        resp.setStatus(dto.getStatus());
        resp.setToken(token);
        return Result.success(resp);
    }

    /**
     * @Description: 公司审核发布岗位不通过
     * @param code
     * @param message 
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:07
     */
    @Override
    public Result<Object> companyVerifyPublishPositionFailed(String code, String message) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        //职位不符
        if(recruiter.getType().equals(RecruiterType.RECRUITER)){
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        }
        Long companyId=recruiter.getCompanyId();
        boolean memberInZSet = cacheUtil.isMemberInZSet(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY + companyId, code);
        //非本公司职位
        if(!memberInZSet) throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_PUBLISH_POSITION_KEY + code);
        PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
        //当前审核状态不在公司审核中
        if(!dto.getStatus().equals(VerifyPublishPositionStatus.VERIFY_COMPANY_REVIEW)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该审核状态无权限修改为审核失败");
        }
        //更新redis，存入managerSet,更改职位信息状态
        dto.setStatus(VerifyPublishPositionStatus.VERIFY_COMPANY_FAILED);
        dto.setFailedMessage(message);
        String dtoNewJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_PUBLISH_POSITION_KEY+code,dtoNewJson);
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 公司审核发布岗位通过
     * @param code 
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:10
     */
    @Override
    public Result<Object> companyVerifyPublishPosition(String code) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        //职位不符
        if(recruiter.getType().equals(RecruiterType.RECRUITER)) throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        Long companyId=recruiter.getCompanyId();
        boolean memberInZSet = cacheUtil.isMemberInZSet(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY + companyId, code);
        //非本公司职位
        if(!memberInZSet) throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_PUBLISH_POSITION_KEY + code);
        PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
        //当前审核状态不在公司审核中
        if(!dto.getStatus().equals(VerifyPublishPositionStatus.VERIFY_COMPANY_REVIEW)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：未处于公司审核中状态");
        }
        //更新redis，存入managerSet,更改职位信息状态
        dto.setStatus(VerifyPublishPositionStatus.VERIFY_MANAGER_REVIEW);
        String dtoNewJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_PUBLISH_POSITION_KEY+code,dtoNewJson);
        //manager-code
        cacheUtil.setZSet(VERIFY_RECRUITER_PUBLISH_POSITION_MANAGER_CODE_KEY,code,System.currentTimeMillis());
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 返回个人发布待审核的岗位 
     * @return Result<List<GetUserPublishPositionResp>>
     * @Author lhb
     * @CreateTime 2025/6/21 10:10
     */
    @Override
    public Result<List<GetUserPublishPositionResp>> getUserPublishPositions() {
        List<GetUserPublishPositionResp> respList=new ArrayList<>();
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        //获取code集合
        Set<String> codesByRank = cacheUtil.getMembersByRank(VERIFY_RECRUITER_PUBLISH_POSITION_RECRUITER_CODE_KEY+recruiter.getUserId(), 0, -1);
        if(codesByRank.isEmpty()) return Result.success(respList);
        List<String> codeList = new ArrayList<>(codesByRank);
        //包装keys集合
        List<String> keys = codesByRank.stream()
                .map(member -> VERIFY_RECRUITER_PUBLISH_POSITION_KEY + member)
                .collect(Collectors.toList());
        List<String> dtoJsons = cacheUtil.multiGet(keys);
        // 使用索引同步遍历 codeList 和 dtoJsons
        for (int i = 0; i < dtoJsons.size(); i++) {
            String dtoJson = dtoJsons.get(i);
            if (dtoJson == null) continue;
            PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
            GetUserPublishPositionResp resp = new GetUserPublishPositionResp();
            // 复制属性
            BeanUtils.copyProperties(dto, resp);
            // 设置对应的 code（来自 codeList）
            resp.setCode(codeList.get(i));
            respList.add(resp);
        }
        return Result.success(respList);
    }

    /**
     * @Description: 返回公司发布待审核的岗位 
     * @return Result<List<GetCompanyPublishPositionResp>>
     * @Author lhb
     * @CreateTime 2025/6/21 10:11
     */
    @Override
    public Result<List<GetCompanyPublishPositionResp>> getCompanyPublishPositions() {
        List<GetCompanyPublishPositionResp> respList=new ArrayList<>();
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        if(recruiter.getType().equals(RecruiterType.RECRUITER)) return Result.error(respList,"无权限");
        //获取code集合
        Set<String> codesByRank = cacheUtil.getMembersByRank(VERIFY_RECRUITER_PUBLISH_POSITION_COM_CODE_KEY+companyId, 0, -1);
        if(codesByRank.isEmpty()) return Result.success(respList);
        List<String> codeList = new ArrayList<>(codesByRank);
        //获取keys集合
        List<String> keys = codesByRank.stream()
                .map(member -> VERIFY_RECRUITER_PUBLISH_POSITION_KEY + member)
                .collect(Collectors.toList());
        List<String> dtoJsons = cacheUtil.multiGet(keys);
        List<Long> userIds = new ArrayList<>();
        if(dtoJsons.isEmpty()) {
            return Result.success(respList);
        }
        // 使用索引同步遍历 codeList 和 dtoJsons
        for (int i = 0; i < dtoJsons.size(); i++) {
            String dtoJson = dtoJsons.get(i);
            if (dtoJson == null) continue;
            PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
            userIds.add(dto.getUserId());
            GetCompanyPublishPositionResp resp=new GetCompanyPublishPositionResp();
            // 复制属性
            BeanUtils.copyProperties(dto, resp);
            // 设置对应的 code（来自 codeList）
            resp.setCode(codeList.get(i));
            respList.add(resp);
        }
        List<User> users = userCommonService.getUsersByUserIds(userIds);
        List<Recruiter> recruiters=recruiterMapper.getRecruiterByUserIds(userIds);
        // 将 users 转换为 Map
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getUserId, user -> user));
        Map<Long, Recruiter> recruiterMap = recruiters.stream()
                .collect(Collectors.toMap(Recruiter::getUserId, recruiterElem -> recruiterElem));
        // 遍历 respList 并设置 name等其他字段
        respList.forEach(resp -> {
            Long userId=resp.getUserId();
            User user = userMap.get(userId);
            Recruiter recruiterElem = recruiterMap.get(userId);
            if (user != null && recruiterElem != null) {
                resp.setName(user.getName());
                resp.setAvatar(user.getAvatar());
                resp.setRole(recruiterElem.getRole());
                resp.setType(recruiterElem.getType());
            }
        });
        return Result.success(respList);
    }

    /**
     * @Description: 跨服务-注册发布岗位
     * @param dto 
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:12
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> registerPublishPosition(PublishPositionDto dto) {
        Position position=new Position();
        BeanUtils.copyProperties(dto, position);
        if(positionMapper.register(position)==0) throw new RuntimeException("注册失败");
        return Result.success();
    }

    /**
     * @Description: 返回个人发布成功的岗位
     * @return Result<List<GetUserPositionResp>>
     * @Author lhb
     * @CreateTime 2025/6/21 10:17
     */
    @Override
    public Result<List<GetUserPositionResp>> getUserPositions() {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long userId=recruiter.getUserId();
        List<GetUserPositionResp> respList=new ArrayList<>();
        List<Position> positionList=positionMapper.getPositionByUserId(userId);
        if(positionList.isEmpty()) {
            return Result.success(respList);
        } else {
            for (Position position:positionList){
                GetUserPositionResp resp=new GetUserPositionResp();
                BeanUtils.copyProperties(position, resp);
                Long positionId=position.getPositionId();
                //添加变更信息
                String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
                if(dtoJson==null) {
                    resp.setStatus(PositionStatus.NORMAL);
                    resp.setFailMessage("");
                    respList.add(resp);
                    continue;
                }
                UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
                resp.setStatus(dto.getStatus());
                resp.setFailMessage(dto.getFailMessage());
                respList.add(resp);
            }
            return Result.success(respList);
        }
    }

    /**
     * @Description: 返回公司发布成功的岗位
     * @return Result<List<GetCompanyPositionResp>>
     * @Author lhb
     * @CreateTime 2025/6/21 10:18
     */
    @Override
    public Result<List<GetCompanyPositionResp>> getCompanyPositions() {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        List<GetCompanyPositionResp> respList=new ArrayList<>();
        List<Position> positionList=positionMapper.getPositionByCompanyId(companyId);
        if(positionList.isEmpty()) return Result.success(respList);
        List<Long> userIds=new ArrayList<>();
        for (Position position:positionList){
            userIds.add(position.getUserId());
            GetCompanyPositionResp resp=new GetCompanyPositionResp();
            BeanUtils.copyProperties(position,resp);
            respList.add(resp);
        }
        List<User> users = userCommonService.getUsersByUserIds(userIds);
        List<Recruiter> recruiters=recruiterMapper.getRecruiterByUserIds(userIds);
        // 将 users 转换为 Map
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getUserId, user -> user));
        Map<Long, Recruiter> recruiterMap = recruiters.stream()
                .collect(Collectors.toMap(Recruiter::getUserId, recruiterElem -> recruiterElem));
        // 遍历 respList 并设置 name等其他字段
        respList.forEach(resp -> {
            Long userId=resp.getUserId();
            User user = userMap.get(userId);
            Recruiter recruiterElem = recruiterMap.get(userId);
            if (user != null && recruiterElem != null) {
                resp.setName(user.getName());
                resp.setAvatar(user.getAvatar());
                resp.setRole(recruiterElem.getRole());
                resp.setType(recruiterElem.getType());
            }
            //添加变更信息
            String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + resp.getPositionId());
            if(dtoJson==null) {
                resp.setStatus(PositionStatus.NORMAL);
                resp.setFailMessage("");
            } else {
                UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
                resp.setStatus(dto.getStatus());
                resp.setFailMessage(dto.getFailMessage());
            }
        });
        return Result.success(respList);
    }

    /**
     * @Description: 修改岗位信息
     * @param req
     * @return Result<UpdatePositionResp>
     * @Author lhb
     * @CreateTime 2025/6/21 10:20
     */
    @Override
    public Result<UpdatePositionResp> updateUserPosition(UpdatePositionReq req) {
        UpdatePositionResp resp=new UpdatePositionResp();
        Long positionId=req.getPositionId();
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        //员工类别
        RecruiterType recruiterType = recruiter.getType();
        Long userId=recruiter.getUserId();
        Position oldPosition=positionMapper.getPositionById(positionId);
        if(oldPosition==null || !Objects.equals(userId, oldPosition.getUserId())) {
            throw new IllegalArgumentException("CLIENT_ERROR：请求体参数有误");
        }
        //构造redis中变更岗位信息的传输体
        PositionDto oldDto=new PositionDto();
        PositionDto newDto=new PositionDto();
        BeanUtils.copyProperties(oldPosition,oldDto);
        BeanUtils.copyProperties(oldPosition,newDto);
        BeanUtils.copyProperties(req,newDto);
        UpdatePositionDto updatePositionDto=new UpdatePositionDto();
        updatePositionDto.setNewDto(newDto);
        updatePositionDto.setOldDto(oldDto);
        updatePositionDto.setFailMessage("");
        //查看是否已经修改过，如果修改过，只需要判断是否从manager的set集合去除
        String oldDtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + req.getPositionId());
        if(oldDtoJson!=null){
            UpdatePositionDto OldDto = JSON.parseObject(oldDtoJson, UpdatePositionDto.class);
            if(OldDto.getStatus().equals(PositionStatus.VERIFY_MANAGER_REVIEW) &&
                    recruiterType.equals(RecruiterType.RECRUITER)){
                //移出管理员审核状态
                cacheUtil.removeMember(VERIFY_RECRUITER_UPDATE_POSITION_MANAGER_ID_KEY,positionId.toString());
            }
        }
        //根据类别储存岗位信息在redis中
        //manager，com，recruiter存储positionId
        //岗位信息的key为positionId
        if(recruiterType.equals(RecruiterType.RECRUITER)) {
            updatePositionDto.setStatus(PositionStatus.VERIFY_COMPANY_REVIEW);
            resp.setStatus(PositionStatus.VERIFY_COMPANY_REVIEW);
        }
        else {
            resp.setStatus(PositionStatus.VERIFY_MANAGER_REVIEW);
            updatePositionDto.setStatus(PositionStatus.VERIFY_MANAGER_REVIEW);
            cacheUtil.setZSet(VERIFY_RECRUITER_UPDATE_POSITION_MANAGER_ID_KEY,positionId.toString(),System.currentTimeMillis());
        }
        cacheUtil.setZSet(VERIFY_RECRUITER_UPDATE_POSITION_COM_ID_KEY+companyId,positionId.toString(),System.currentTimeMillis());
        cacheUtil.setZSet(VERIFY_RECRUITER_UPDATE_POSITION_RECRUITER_ID_KEY+userId,positionId.toString(),System.currentTimeMillis());
        String dtoJson = JSON.toJSONString(updatePositionDto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_UPDATE_POSITION_KEY+positionId,dtoJson);
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        resp.setToken(token);
        return Result.success(resp);
    }

    /**
     * @Description: 删除岗位
     * @param positionId
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:20
     */
    @Override
    public Result<Object> deletePosition(Long positionId) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long userId=recruiter.getUserId();
        Position position=positionMapper.getPositionById(positionId);
        if(position==null ||!position.getUserId().equals(userId)) {
            throw new IllegalArgumentException("CLIENT_ERROR：请求参数有误");
        }
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson!=null) throw new IllegalArgumentException("VALIDATION_ERROR：请先取消变更再删除岗位");
        if(positionMapper.deletePositionById(positionId)==0) throw new RuntimeException("删除失败");
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 取消变更岗位信息
     * @param positionId
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:21
     */
    @Override
    public Result<Object> cancelUpdateUserPosition(Long positionId) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        Long userId=recruiter.getUserId();
        Position position=positionMapper.getPositionById(positionId);
        if(position==null ||!position.getUserId().equals(userId)) {
            throw new IllegalArgumentException("CLIENT_ERROR：请求参数有误");
        }
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson==null) throw new IllegalArgumentException("VALIDATION_ERROR：该岗位未修改");
        UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
        if(dto.getStatus().equals(PositionStatus.VERIFY_MANAGER_REVIEW)) {
            cacheUtil.removeMember(VERIFY_RECRUITER_UPDATE_POSITION_MANAGER_ID_KEY,positionId.toString());
        }
        cacheUtil.removeMember(VERIFY_RECRUITER_UPDATE_POSITION_RECRUITER_ID_KEY+userId,positionId.toString());
        cacheUtil.removeMember(VERIFY_RECRUITER_UPDATE_POSITION_COM_ID_KEY+companyId,positionId.toString());
        cacheUtil.deleteKeySafely(VERIFY_RECRUITER_UPDATE_POSITION_KEY+positionId);
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 查看岗位变更信息
     * @param positionId
     * @return Result<JobChangeInformationResp>
     * @Author lhb
     * @CreateTime 2025/6/21 10:22
     */
    @Override
    public Result<JobChangeInformationResp> checkPositionChangeInformation(Long positionId) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Position position=positionMapper.getPositionById(positionId);
        if(position==null) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该岗位未修改");
        }
        if(!position.getUserId().equals(recruiter.getUserId()) &&
                recruiter.getType().equals(RecruiterType.RECRUITER)) {
            //只有发布人和管理员可以查看变更
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        }
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson==null) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该岗位未修改");
        }
        //初始化响应体
        JobChangeInformationResp resp=new JobChangeInformationResp();
        resp.setOldJobMessageResp(new JobMessageResp());
        resp.setNewJobMessageResp(new JobMessageResp());
        UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
        //字段映射
        Long userId = dto.getOldDto().getUserId();
        Recruiter positionRecruiter = recruiterMapper.getRecruiterByUserId(userId);
        User user = userCommonService.getUserByUserId(userId);
        BeanUtils.copyProperties(dto.getOldDto(), resp.getOldJobMessageResp());
        BeanUtils.copyProperties(dto.getNewDto(),resp.getNewJobMessageResp());
        //映射用户信息字段
        BeanUtils.copyProperties(user, recruiter);
        BeanUtils.copyProperties(recruiter, resp.getOldJobMessageResp());
        BeanUtils.copyProperties(recruiter, resp.getNewJobMessageResp());
        resp.setStatus(dto.getStatus());
        resp.setFailMessage(dto.getFailMessage());
        return Result.success(resp);
    }

    /**
     * @Description: 公司审核岗位变更通过
     * @param positionId
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:23
     */
    @Override
    public Result<Object> companyVerifyChangePosition(Long positionId) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        if(recruiter.getType().equals(RecruiterType.RECRUITER)){
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        }
        boolean memberInZSet = cacheUtil.isMemberInZSet(VERIFY_RECRUITER_UPDATE_POSITION_COM_ID_KEY + companyId, positionId.toString());
        //非本公司职位
        if(!memberInZSet) throw new IllegalArgumentException("VALIDATION_ERROR：非本公司职位");
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson==null) throw new IllegalArgumentException("VALIDATION_ERROR：该岗位未修改");
        UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
        if(!dto.getStatus().equals(PositionStatus.VERIFY_COMPANY_REVIEW)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该职位未处于公司审核状态");
        }
        //设置为管理员待审核状态
        dto.setStatus(PositionStatus.VERIFY_MANAGER_REVIEW);
        String dtoNewJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_UPDATE_POSITION_KEY+positionId,dtoNewJson);
        cacheUtil.setZSet(VERIFY_RECRUITER_UPDATE_POSITION_MANAGER_ID_KEY,positionId.toString(),System.currentTimeMillis());
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 公司审核岗位变更不通过
     * @param positionId
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:23
     */
    @Override
    public Result<Object> companyVerifyChangePositionFailed(Long positionId, String failMessage) {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        if(recruiter.getType().equals(RecruiterType.RECRUITER)){
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限");
        }
        boolean memberInZSet = cacheUtil.isMemberInZSet(VERIFY_RECRUITER_UPDATE_POSITION_COM_ID_KEY + companyId, positionId.toString());
        //非本公司职位
        if(!memberInZSet) throw new IllegalArgumentException("VALIDATION_ERROR：非本公司职位");
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson==null) throw new IllegalArgumentException("VALIDATION_ERROR：该岗位未修改");
        UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
        if(!dto.getStatus().equals(PositionStatus.VERIFY_COMPANY_REVIEW)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该职位未处于公司审核状态");
        }
        //设置为公司审核不通过状态
        dto.setStatus(PositionStatus.VERIFY_COMPANY_FAILED);
        dto.setFailMessage(failMessage);
        String dtoNewJson = JSON.toJSONString(dto);
        cacheUtil.setNoTtl(VERIFY_RECRUITER_UPDATE_POSITION_KEY+positionId,dtoNewJson);
        String token=userCommonService.updateRedisUserToken(recruiter.getUserId(),RECRUITER_KEY,authConfig.getJwtRecruiterSecret(),RECRUITER_TTL,TimeUnit.DAYS);
        if(token==null) throw new RuntimeException("token生成失败");
        return Result.success(token);
    }

    /**
     * @Description: 跨服务-变更岗位
     * @param req
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/6/21 10:24
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> changePositionInformation(RCrossChangePositionReq req) {
        Long potionId= req.getPositionId();
        Long userId=req.getUserId();
        Position position = positionMapper.getPositionById(potionId);
        if(!Objects.equals(position.getUserId(), userId)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：请求体有误");
        }
        BeanUtils.copyProperties(req,position);
        if(positionMapper.updatePosition(position)==0) throw new RuntimeException("修改失败");
        return Result.success();
    }

    /**
     * @Description:  获取变更待审核岗位的列表
     * @return Result<List<CompanyPendingUpdateJobResp>>
     * @Author lhb
     * @CreateTime 2025/7/9 22:37
     */
    @Override
    public Result<List<CompanyPendingUpdateJobResp>> getUpdatedPositionLists() {
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        Long companyId=recruiter.getCompanyId();
        List<CompanyPendingUpdateJobResp> respList=new ArrayList<>();
        if(recruiter.getType().equals(RecruiterType.RECRUITER)) return Result.error(respList,"无权限");
        Set<String> positionIdByRank = cacheUtil.getMembersByRank(
                VERIFY_RECRUITER_UPDATE_POSITION_COM_ID_KEY+companyId, 0, -1);
        if(positionIdByRank.isEmpty()) return Result.success(respList);
        List<String> keys = positionIdByRank.stream()
                .map(member -> VERIFY_RECRUITER_UPDATE_POSITION_KEY + member)
                .toList();
        List<String> dtoJsons = cacheUtil.multiGet(keys);
        if(dtoJsons.isEmpty()) {
            return Result.success(respList);
        }
        List<Long> userIds = new ArrayList<>();
        for(String dtoJson:dtoJsons){
            UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
            //构建userIds
            userIds.add(dto.getOldDto().getUserId());
            CompanyPendingUpdateJobResp resp=new CompanyPendingUpdateJobResp();
            // 确保 oldPositionMessage 和 newPositionMessage 已经初始化
            resp.setNewJobMessageResp(new JobMessageResp());
            resp.setOldJobMessageResp(new JobMessageResp());
            //字段映射
            BeanUtils.copyProperties(dto.getOldDto(),resp.getOldJobMessageResp());
            BeanUtils.copyProperties(dto.getNewDto(),resp.getNewJobMessageResp());
            resp.setStatus(dto.getStatus());
            respList.add(resp);
        }
        List<User> users = userCommonService.getUsersByUserIds(userIds);
        List<Recruiter> recruiters=recruiterMapper.getRecruiterByUserIds(userIds);
        // 将 users 转换为 Map
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getUserId, user -> user));
        Map<Long, Recruiter> recruiterMap = recruiters.stream()
                .collect(Collectors.toMap(Recruiter::getUserId, recruiterElem -> recruiterElem));
        // 遍历 respList 并设置 name等其他字段
        respList.forEach(resp -> {
            Long userId=resp.getOldJobMessageResp().getUserId();
            User user = userMap.get(userId);
            Recruiter recruiterElem = recruiterMap.get(userId);
            if (user != null && recruiterElem != null) {
                //旧
                resp.getOldJobMessageResp().setName(user.getName());
                resp.getOldJobMessageResp().setAvatar(user.getAvatar());
                resp.getOldJobMessageResp().setRole(recruiterElem.getRole());
                resp.getOldJobMessageResp().setType(recruiterElem.getType());
                //新
                resp.getNewJobMessageResp().setName(user.getName());
                resp.getNewJobMessageResp().setAvatar(user.getAvatar());
                resp.getNewJobMessageResp().setRole(recruiterElem.getRole());
                resp.getNewJobMessageResp().setType(recruiterElem.getType());
            }
        });
        return Result.success(respList);
    }

    /**
     * @Description: 根据唯一标识返回个人发布待审核的岗位
     * @param code
     * @return Result<GetUserPublishPositionResp>
     * @Author lhb
     * @CreateTime 2025/7/16 15:32
     */
    @Override
    public Result<GetUserPublishPositionDetailResp> getUserPublishPositionByCode(String code) {
        GetUserPublishPositionDetailResp resp = new GetUserPublishPositionDetailResp();
        Recruiter recruiter=TLUtil.get(TLUtil.R);
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_PUBLISH_POSITION_KEY + code);
        if(dtoJson == null) {
            throw new NullPointerException("无此岗位信息");
        }
        PublishPositionDto dto = JSON.parseObject(dtoJson, PublishPositionDto.class);
        if(!dto.getCompanyId().equals(recruiter.getCompanyId())) {
            //非本公司不可查看
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限查看岗位");
        }
        //映射发布方信息字段
        if(dto.getUserId().equals(recruiter.getUserId())) {
            BeanUtils.copyProperties(recruiter, resp);
        } else {
            User user = userCommonService.getUserByUserId(dto.getUserId());
            Recruiter recruiterById = recruiterMapper.getRecruiterByUserId(dto.getUserId());
            resp.setAvatar(user.getAvatar());
            resp.setName(user.getName());
            resp.setRole(recruiterById.getRole());
            resp.setType(recruiterById.getType());
        }
        if(!dto.getUserId().equals(recruiter.getUserId()) &&
                recruiter.getType().equals(RecruiterType.RECRUITER)) {
            //只有发布人和管理层能查看
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限查看岗位");
        }
        BeanUtils.copyProperties(dto, resp);
        resp.setCode(code);
        return Result.success(resp);
    }

    /**
     * @Description: 根据职位id返回个人发布成功的岗位
     * @param positionId
     * @return Result<GetUserPositionResp>
     * @Author lhb
     * @CreateTime 2025/7/16 15:41
     */
    @Override
    public Result<GetUserPositionDetailResp> getUserPositionById(Long positionId) {
        GetUserPositionDetailResp resp=new GetUserPositionDetailResp();
        Recruiter recruiter = TLUtil.get(TLUtil.R);
        Position position = positionMapper.getPositionById(positionId);
        if(!position.getCompanyId().equals(recruiter.getCompanyId())) {
            throw new IllegalArgumentException("VALIDATION_ERROR：无权限查看其他公司的岗位信息");
        }
        //映射发布方信息字段
        if(position.getUserId().equals(recruiter.getUserId())) {
            BeanUtils.copyProperties(recruiter, resp);
        } else {
            User user = userCommonService.getUserByUserId(position.getUserId());
            Recruiter recruiterById = recruiterMapper.getRecruiterByUserId(position.getUserId());
            resp.setAvatar(user.getAvatar());
            resp.setName(user.getName());
            resp.setRole(recruiterById.getRole());
            resp.setType(recruiterById.getType());
        }
        BeanUtils.copyProperties(position, resp);
        //添加变更信息
        String dtoJson = cacheUtil.get(VERIFY_RECRUITER_UPDATE_POSITION_KEY + positionId);
        if(dtoJson==null) {
            resp.setStatus(PositionStatus.NORMAL);
            resp.setFailMessage("");
            return Result.success(resp);
        }
        UpdatePositionDto dto = JSON.parseObject(dtoJson, UpdatePositionDto.class);
        resp.setStatus(dto.getStatus());
        resp.setFailMessage(dto.getFailMessage());
        return Result.success(resp);
    }


//    /**
//     * @Description: 跨服务被调用方，搜索职位或者公司，包含智能推荐
//     * @param req
//     * @return Result<RCrossSearchJobOrCompanyResp>
//     * @Author lhb
//     * @CreateTime 2025/6/25 11:08
//     */
//    @Override
//    public Result<Object> searchJobOrCompany(RCrossSearchJobOrCompanyReq req) {
//        Seeker seeker=req.getSeeker();
//        String content = req.getContent();
//        String location = req.getLocation();
//        RCrossSearchJobOrCompanyResp resp=new RCrossSearchJobOrCompanyResp();
//        //防止为空
//        resp.setRCrossSearchCompanyList(new ArrayList<>());
//        resp.setRCrossSearchPositionList(new ArrayList<>());
//        String cleanedContent = content.replaceAll("有限|公司", "");
//        //当内容为空字符串，直接智能推荐
//        if(cleanedContent.isEmpty()){
//            List<Position> smartPositionList = smartRecommendJobs(seeker, location);
//            if (smartPositionList != null && !smartPositionList.isEmpty()) {
//                List<RCrossSearchPosition> rCrossSearchPositionList = processSearchJobs(smartPositionList);
//                resp.setRCrossSearchPositionList(rCrossSearchPositionList);
//            }
//            return Result.success(resp);
//        }
//        //根据内容搜索公司，并返回这个公司的所有职位
//        List<Company> companyList=companyMapper.getCompanyListByName(cleanedContent);
//        //提取所有 company ID
//        List<Long> companyIds = companyList.stream()
//                .map(Company::getCompanyId)
//                .filter(Objects::nonNull)
//                .toList();
//        List<Position> positionByCompanyList = new ArrayList<>();
//        //类型转换，查询公司员工数和职位数
//        if (!companyIds.isEmpty()) {
//            for (Company company:companyList){
//                Long companyId=company.getCompanyId();
//                Long recruiterNum=recruiterMapper.getRecruiterNumByCompanyId(companyId);
//                Long positionNum=positionMapper.getPositionNumByCompanyId(companyId);
//                RCrossSearchCompany companyResp=new RCrossSearchCompany();
//                BeanUtils.copyProperties(company,companyResp);
//                companyResp.setRecruiterNum(recruiterNum);
//                companyResp.setPositionNum(positionNum);
//                resp.getRCrossSearchCompanyList().add(companyResp);
//            }
//            positionByCompanyList = positionMapper.getPositionByCompanyIds(companyIds);
//        }
//        //根据内容和地点再搜索岗位
//        List<Position> positionByNameList=positionMapper.getPositionByNameAndLocation(cleanedContent,location);
//        // 合并两部分结果
//        List<Position> positionList = new ArrayList<>();
//        positionList.addAll(positionByCompanyList);
//        positionList.addAll(positionByNameList);
//        //查看是否需要去重，当公司查询为空或者职位为空就不要去重
//        if(!positionList.isEmpty()&&!companyList.isEmpty()){
//            if(!positionByNameList.isEmpty()&&!positionByCompanyList.isEmpty()){
//                // 使用 toMap 去重（推荐）
//                Map<Long, Position> uniquePositions = positionList.stream()
//                        .collect(Collectors.toMap(
//                                Position::getPositionId,
//                                position -> position,
//                                (existing, replacement) -> existing // 保留第一个出现的
//                        ));
//                // 转换为 List
//                positionList = new ArrayList<>(uniquePositions.values());
//            }
//            //构造搜索返回的职位响应体列表
//            List<RCrossSearchPosition> rCrossSearchPositionList=processSearchJobs(positionList);
//            resp.setRCrossSearchPositionList(rCrossSearchPositionList);
//            return Result.success(resp);
//        }
//        //构造搜索返回的职位响应体列表
//        if(!positionList.isEmpty()){
//            List<RCrossSearchPosition> rCrossSearchPositionList=processSearchJobs(positionList);
//            resp.setRCrossSearchPositionList(rCrossSearchPositionList);
//        }
//        else {
//            //如果公司列表和职位列表都是空，智能推荐
//            if(companyList.isEmpty()){
//                List<Position> smartPositionList = smartRecommendJobs(seeker, location);
//                if (smartPositionList != null && !smartPositionList.isEmpty()) {
//                    List<RCrossSearchPosition> rCrossSearchPositionList = processSearchJobs(smartPositionList);
//                    resp.setRCrossSearchPositionList(rCrossSearchPositionList);
//                }
//            }
//        }
//        return Result.success(resp);
//    }
//
//    /**
//     * @Description: 智能推荐
//     * @param seeker
//     * @param location
//     * @return List<Position>
//     * @Author lhb
//     * @CreateTime 2025/6/26 9:27
//     */
//    private List<Position> smartRecommendJobs(Seeker seeker, String location) {
//        String expectedPosition = seeker.getExpectedPosition();
//        String expectedIndustry = seeker.getExpectedIndustry();
//        List<Position> positionByNameList=new ArrayList<>();
//        List<Position> positionByIndustry=new ArrayList<>();
//        //用户未设置期望岗位和期望行业时，不查询
//        if(expectedPosition!=null&&!expectedPosition.isEmpty()){
//            positionByNameList=positionMapper.getPositionByNameAndLocation(expectedPosition,location);
//        }
//        if(expectedIndustry!=null &&!expectedIndustry.isEmpty()){
//            positionByIndustry=positionMapper.getPositionByJobType(expectedIndustry,location);
//        }
//        // 合并并去重，保留 positionByNameList 的元素在前
//        List<Position> mergedList = new ArrayList<>();
//        if (!positionByNameList.isEmpty() && !positionByIndustry.isEmpty()) {
//            // 使用 Stream.concat 合并两个列表，先处理 positionByNameList，再处理 positionByIndustry
//            Map<Long, Position> uniquePositions = Stream.concat(
//                            positionByNameList.stream(),
//                            positionByIndustry.stream()
//                    )
//                    .collect(Collectors.toMap(
//                            Position::getPositionId,
//                            position -> position,
//                            (existing, replacement) -> existing, // 保留第一个出现的
//                            LinkedHashMap::new // 保持插入顺序
//                    ));
//            // 转换为 List
//            mergedList = new ArrayList<>(uniquePositions.values());
//        } else if (!positionByNameList.isEmpty()) {
//            // 如果其中一个列表为空，直接使用非空列表
//            mergedList = new ArrayList<>(positionByNameList);
//        } else if (!positionByIndustry.isEmpty()) {
//            // 如果另一个列表也为空，直接使用非空列表
//            mergedList = new ArrayList<>(positionByIndustry);
//        }else {
//            //当根据期望岗位和期望行业查询为空或者未设置基本信息时，根据地点查询
//            mergedList=positionMapper.getPositionByLocation(location);
//        }
//        //根据期望薪资进行筛选，看期望薪资是否在这个区间内
//        return mergedList;
//    }



















    /**
     * @Description: 跨服务-搜索岗位或者公司
     * @param req
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/7/15 11:42
     */
    @Override
    public Result<Object> searchJobOrCompany(RCrossSearchJobOrCompanyReq req) {
        String location = req.getLocation();
        String content = req.getContent();
        Seeker seeker = req.getSeeker();
        boolean isHotCity = cacheUtil.isMemberInSet(HOT_POSITION_CITIES_KEY, location);
        System.out.println("是否为热门："+isHotCity);
        //构造响应体
        RCrossSearchJobOrCompanyResp resp=new RCrossSearchJobOrCompanyResp();
        resp.setRCrossSearchCompanyList(new ArrayList<>());
        resp.setRCrossSearchPositionList(new ArrayList<>());
        String cleanedContent = content.replaceAll("有限|公司", "");
        List<Position> positionList = new ArrayList<>();
        if(isHotCity) {
            //热门城市
            if(cleanedContent.isEmpty()) {
                System.out.println("热门，搜索内容为空");
                //智能推荐
                positionList = smartRecommendJobs(seeker, location);
            } else {
                System.out.println("热门，搜索内容非空");
                //查询公司，子方法会填充resp的公司响应体
                List<Position> positionByCompanyList = searchCompany(resp,cleanedContent);
                //根据内容和地点再搜索岗位
                List<Position> positionByNameList=positionMapper.getPositionByNameAndLocation(cleanedContent,location);
                // 合并两部分结果
                positionList = mergeAndDeduplicate(positionByCompanyList, positionByNameList);
                //职位数量不够，智能推荐
                if(positionList.size() < SMART_START_MIN_POSITIONS) {
                    System.out.println("热门，搜索内容非空，数量不足");
                    List<Position> smartPositionList = smartRecommendJobs(seeker, location);
                    positionList = mergeAndDeduplicate(positionList, smartPositionList);
                }
            }
        } else {
            //冷门城市
            if(cleanedContent.isEmpty()) {
                System.out.println("冷门，搜索内容为空");
                //查询本城市所有职位
                List<Position> positionListAll = positionMapper.getPositionByLocation("");
                //地点不限制智能推荐
                List<Position> smartPositionList = smartRecommendJobs(seeker, "");
                positionList = mergeAndDeduplicate(positionListAll, smartPositionList);
            } else {
                System.out.println("冷门，搜索内容非空");
                //查询公司，子方法会填充resp的公司响应体
                List<Position> positionByCompanyList = searchCompany(resp,cleanedContent);
                //根据内容和地点再搜索岗位
                List<Position> positionByNameList=positionMapper.getPositionByNameAndLocation(cleanedContent, location);
                positionList = mergeAndDeduplicate(positionByNameList, positionByCompanyList);
                //地点不限制智能推荐
                List<Position> smartPositionList = smartRecommendJobs(seeker, "");
                positionList = mergeAndDeduplicate(positionList, smartPositionList);
            }
        }
        //构造搜索返回的职位响应体列表
        List<RCrossSearchPosition> rCrossSearchPositionList=processSearchJobs(positionList);
        resp.setRCrossSearchPositionList(rCrossSearchPositionList);
        return Result.success(resp);
    }

    /**
     * @Description: 智能推荐，三个常量待定义
     * @param seeker
     * @param location
     * @return List<Position>
     * @Author lhb
     * @CreateTime 2025/7/15 15:14
     */
    private List<Position> smartRecommendJobs(Seeker seeker, String location) {
        //如果location是"",不会执行只根据地点搜索，因为根据偏好时已经忽略地点
        String expectedPosition = seeker.getExpectedPosition();
        String expectedIndustry = seeker.getExpectedIndustry();
        List<Position> positionByNameList=new ArrayList<>();
        List<Position> positionByIndustry=new ArrayList<>();
        //用户未设置期望岗位和期望行业时，不查询
        if(expectedPosition!=null&&!expectedPosition.isEmpty()){
            positionByNameList=positionMapper.getPositionByNameAndLocation(expectedPosition,location);
        }
        if(expectedIndustry!=null &&!expectedIndustry.isEmpty()){
            positionByIndustry=positionMapper.getPositionByJobType(expectedIndustry,location);
        }
        // 合并并去重，保留 positionByNameList 的元素在前
        List<Position> mergedList = mergeAndDeduplicate(positionByNameList, positionByIndustry);
        //当根据期望岗位和期望行业查询为空或者未设置基本信息时，或者数额不够时，智能查询
        if(mergedList.size() < SMART_AGAIN_MIN_POSITIONS) {
            List<Position> positionByLocation = positionMapper.getPositionByLocation(location);
            mergedList = mergeAndDeduplicate(mergedList, positionByLocation);
        }
        return mergedList;
    }

    /**
     * @Description: 合并并去重
     * @param list1
     * @param list2 
     * @return List<Position>
     * @Author lhb
     * @CreateTime 2025/7/15 14:38
     */
    private List<Position> mergeAndDeduplicate(List<Position> list1, List<Position> list2) {
        Map<Long, Position> uniqueMap = new LinkedHashMap<>();
        for (Position p : list1) {
            uniqueMap.put(p.getPositionId(), p);
        }
        for (Position p : list2) {
            uniqueMap.putIfAbsent(p.getPositionId(), p);
        }
        return new ArrayList<>(uniqueMap.values());
    }

    /**
     * @Description: 查询公司，返回公司职位列表，填充响应体
     * @param resp
     * @param cleanedContent
     * @return List<Position>
     * @Author lhb
     * @CreateTime 2025/7/15 15:14
     */
    private List<Position> searchCompany(RCrossSearchJobOrCompanyResp resp, String cleanedContent) {
        //提取所有 company ID
        List<Company> companyList=companyMapper.getCompanyListByName(cleanedContent);
        List<Long> companyIds = companyList.stream()
                .map(Company::getCompanyId)
                .filter(Objects::nonNull)
                .toList();
        List<Position> positionByCompanyList = new ArrayList<>();
        //类型转换，查询公司员工数和职位数
        if (!companyIds.isEmpty()) {
            for (Company company:companyList){
                Long companyId=company.getCompanyId();
                Long recruiterNum=recruiterMapper.getRecruiterNumByCompanyId(companyId);
                Long positionNum=positionMapper.getPositionNumByCompanyId(companyId);
                RCrossSearchCompany companyResp=new RCrossSearchCompany();
                BeanUtils.copyProperties(company,companyResp);
                companyResp.setRecruiterNum(recruiterNum);
                companyResp.setPositionNum(positionNum);
                resp.getRCrossSearchCompanyList().add(companyResp);
            }
            positionByCompanyList = positionMapper.getPositionByCompanyIds(companyIds);
        }
        return positionByCompanyList;
    }

    /**
     * @Description: 构造搜索返回的职位响应体列表
     * @param positionList
     * @return List<RCrossSearchPosition>
     * @Author lhb
     * @CreateTime 2025/6/27 9:30
     */
    private List<RCrossSearchPosition> processSearchJobs(List<Position> positionList) {
        List<RCrossSearchPosition> respList=new ArrayList<>();
        for (Position position:positionList){
            RCrossSearchPosition resp=new RCrossSearchPosition();
            BeanUtils.copyProperties(position,resp);
            Company company = recruiterCommonService.getCompanyMessage(position.getCompanyId());
            resp.setCompanyAvatar(company.getAvatar());
            resp.setCompanyName(company.getName());
            respList.add(resp);
        }
        return respList;
    }


}
